
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SampleCode.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkGraphics.h"
#include "SkRandom.h"

#include <pthread.h>

static void call_measure()
    {
    SkPaint paint;
    uint16_t text[32];
    SkRandom rand;

    paint.setAntiAlias(true);
    paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
    for (int j = 0; j < SK_ARRAY_COUNT(text); j++)
        text[j] = (uint16_t)((rand.nextU() & 0xFF) + 32);

    for (int i = 9; i < 36; i++)
        {
        SkPaint::FontMetrics m;

        paint.setTextSize(SkIntToScalar(i));
        paint.getFontMetrics(&m);
        paint.measureText(text, sizeof(text));
        }
    }

static void call_draw(SkCanvas* canvas)
    {
    SkPaint paint;
    uint16_t text[32];
    SkRandom rand;

    paint.setAntiAlias(true);
    paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
    for (int j = 0; j < SK_ARRAY_COUNT(text); j++)
        text[j] = (uint16_t)((rand.nextU() & 0xFF) + 32);

    SkScalar x = SkIntToScalar(10);
    SkScalar y = SkIntToScalar(20);

    canvas->drawColor(SK_ColorWHITE);
    for (int i = 9; i < 36; i++)
        {
        SkPaint::FontMetrics m;

        paint.setTextSize(SkIntToScalar(i));
        paint.getFontMetrics(&m);
        canvas->drawText(text, sizeof(text), x, y, paint);
        y += m.fDescent - m.fAscent;
        }
    }

static bool gDone;

static void* measure_proc(void* context)
    {
    while (!gDone)
        {
        call_measure();
        }
    return NULL;
    }

static void* draw_proc(void* context)
    {
    SkBitmap* bm = (SkBitmap*)context;
    SkCanvas    canvas(*bm);

    while (!gDone)
        {
        call_draw(&canvas);
        }
    return NULL;
    }

class FontCacheView : public SampleView
    {
    public:
        enum { N = 4 };

        pthread_t   fMThreads[N];
        pthread_t   fDThreads[N];
        SkBitmap    fBitmaps[N];

        FontCacheView()
            {
            gDone = false;
            for (int i = 0; i < N; i++)
                {
                int status;

                status = pthread_create(&fMThreads[i], NULL,  measure_proc, NULL);
                SkASSERT(0 == status);

                fBitmaps[i].setConfig(SkBitmap::kRGB_565_Config, 320, 240);
                fBitmaps[i].allocPixels();
                status = pthread_create(&fDThreads[i], NULL,  draw_proc, &fBitmaps[i]);
                SkASSERT(0 == status);
                }
            this->setBGColor(0xFFDDDDDD);
            }

        virtual ~FontCacheView()
            {
            gDone = true;
            for (int i = 0; i < N; i++)
                {
                void* ret;
                int status = pthread_join(fMThreads[i], &ret);
                SkASSERT(0 == status);
                status = pthread_join(fDThreads[i], &ret);
                SkASSERT(0 == status);
                }
            }

    protected:
        // overrides from SkEventSink
        virtual bool onQuery(SkEvent* evt)
            {
            if (SampleCode::TitleQ(*evt))
                {
                SampleCode::TitleR(evt, "FontCache");
                return true;
                }
            return this->INHERITED::onQuery(evt);
            }

        virtual void onDrawContent(SkCanvas* canvas)
            {
            SkScalar x = 0;
            SkScalar y = 0;
            for (int i = 0; i < N; i++)
                {
                canvas->drawBitmap(fBitmaps[i], x, y);
                x += SkIntToScalar(fBitmaps[i].width());
                }
            this->inval(NULL);
            }

    private:
        typedef SampleView INHERITED;
    };

//////////////////////////////////////////////////////////////////////////////

static SkView* MyFactory()
    {
    return new FontCacheView;
    }
static SkViewRegister reg(MyFactory);

